package main

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
	"sync"

	"github.com/gorilla/websocket"
	"golang.org/x/net/context"
)

type Message struct {
	Time     string `json:"time"`
	UserName string `json:"user_name"`
	Type     string `json:"type"`
	Context  string `json:"context"`
}

//因为没有前端，所有要求客户端输入格式是 类型-内容 如ready-ready, chat-你好，chess-(8,2)(4,2)
const (
	ready    = "ready"
	chat     = "chat"
	system   = "system"
	chess    = "chess"
	withdraw = "withdraw"
)

type Connection struct {
	conn *websocket.Conn
	mu   sync.Mutex
}

var user string
var addReady uint

var wg sync.WaitGroup

func main() {
	wg.Add(2)
	userName := flag.String("username", "error", "Input Your Username")
	passWord := flag.String("password", "error", "Input Your password")
	group := flag.Int("group", 1, "Input your group")
	flag.Parse()
	//origin := "http://127.0.0.1:8081"
	wsConn := "ws://lightos.cloud:8081/ws?group=" + strconv.Itoa(*group) + "&username=" + *userName + "&password=" + *passWord
	fmt.Println(wsConn)
	conn, _, err := websocket.DefaultDialer.Dial(wsConn, nil)
	if err != nil {
		log.Println(err)
		conn.Close()
	}
	user = *userName
	fmt.Println("请输入内容")
	c := new(Connection)
	c.conn = conn
	cont, cancel := context.WithCancel(context.Background())
	go c.Receive(cont)
	go c.Send(cont, cancel)
	wg.Wait()
}

func Input() []byte {
	reader := bufio.NewReader(os.Stdin)
	by, _, err := reader.ReadLine()
	if err != nil {
		log.Println(err)
		return []byte{}
	}
	return by
}

func (c *Connection) Receive(ctx context.Context) {
	for {
		select {
		case <-ctx.Done():
			fmt.Println("ctx.Done()")
			wg.Done()
			return
		default:
			_, msg, err := c.conn.ReadMessage()
			if string(msg) == "ping" { //接收到的是一个来自服务器的ping msg
				//fmt.Println("回一个pong消息")
				err := c.PongMessage()
				if err != nil {
					log.Println(err)
					return
				}
			} else { //如果不是ping msg打印
				m := DeCode(string(msg))
				if m.Context == "可以开下了" {
					addReady = 1
				}
				if err != nil {
					log.Println(err)
					c.conn.Close().Error()
				}
				fmt.Println("receive:", string(msg))
			}
		}
	}
}

func (c *Connection) Send(ctx context.Context, cancel context.CancelFunc) {
	for {
		input := Input()
		//输入格式不正确，重新输入
		if msg, ok := HandInputString(string(input)); !ok {
			fmt.Println(msg)
			continue
		}
		if string(input) == "-1" {
			wg.Done()
			cancel()
			return
		}
		c.mu.Lock()
		err := c.conn.WriteMessage(websocket.TextMessage, []byte(input))
		c.mu.Unlock()
		if err != nil {
			log.Println(err)
			return
		}
		log.Println("SEND：", string(input))
	}
}

func (c *Connection) PongMessage() (err error) {
	//defer log.Println("pong suc")
	//err = c.conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
	if err != nil {
		log.Println(err)
		return err
	}
	c.mu.Lock()
	c.conn.WriteMessage(websocket.TextMessage, []byte("pong"))
	c.mu.Unlock()
	return
}

func HandInputString(s string) (msg string, ok bool) {
	strS := strings.SplitN(s, "-", 2)
	fmt.Println("strS=", strS)
	if len(strS) == 1 {
		return "输入格式错误", false
	}
	if strS[0] != ready && strS[0] != chat && strS[0] != system && strS[0] != chess && strS[0] != "all" && strS[0] != withdraw {
		return "输入格式错误", false
	}
	if addReady != 1 && strS[0] == chess {
		return "有玩家未准备", false
	}
	return "", true
}

//func Handle(s string) (ty string) {
//	strS := strings.SplitN(s, "-", 2)
//	return strS[0]
//}

func DeCode(s string) (m *Message) {
	m = new(Message)
	err := json.Unmarshal([]byte(s), m)
	if err != nil {

	}
	return m
}
